﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Xss.Data.Common;
using Xss.Data.Common.SessionStore;
using Xss.Logging;
using System.Data;

namespace Xss.Data
{

    public class AdoSession : IAdoSession
    {
        ILog logger = LogManager.GetCurrentClassLogger();

        public AdoSession(IAdoRequest request)
        {
            _request = request;
            _sessionId = Guid.NewGuid().ToString();
            _source = AdoRegistry.GetDbSource(request.DataSource);
            _dbProvider = Xss.Data.Common.DbProviderFactory.GetDbProvider(_source.DbProvider);
            _dbProvider.ConnectionString = _source.ResetConnectionString(request.ExtendProperies);
            _holder = new AdoHolder(_request.EnableTransaction, this);
        }

        readonly string _sessionId;
        IAdoRequest _request;
        IAdoResponse _response;
        IDbSource _source;
        Xss.Data.Common.IDbProvider _dbProvider;
        IAdoHolder _holder;

        public string SessionId
        {
            get { return _sessionId; }
        }

        public IAdoRequest Request
        {
            get { return _request; }
        }

        public IAdoResponse Response
        {
            get { return _response; }
        }

        public void OpenSession()
        {
            logger.Debug("OpenSession Begin");
            _response = new AdoResponse();

            var connection = OpenConnection();
            _response.Result = _holder.ExecuteTransaction(
                (s) => { return Request.Mapper.Execute(); }
                );

            _response.Message = Request.Mapper.Message;

            logger.Debug("OpenSession End");
        }

        public void Close()
        {

            logger.Debug("Close Session");
        }

        public void Dispose()
        {
            Close();
            _request = null;
            _source = null;
            _dbProvider = null;
        }

        public System.Data.IDbConnection OpenConnection()
        {
            if (_holder.DbConnection.State != ConnectionState.Open)
            {
                try
                {
                    _holder.DbConnection.Open();
                    if (logger.IsDebugEnabled)
                    {
                        logger.Debug(string.Format("Open Connection \"{0}\" to \"{1}\".", _source.Name, _source.DbProvider));
                    }
                }
                catch (Exception ex)
                {
                    throw new Exception(string.Format("Unable to open connection \"{0}\" of \"{1}\".", _source.DbProvider, _dbProvider.ConnectionString), ex);
                }
            }
            return _holder.DbConnection;
        }

        public Xss.Data.Common.IDbProvider DbProvider
        {
            get { return _dbProvider; }
        }


        public IAdoHolder Holder
        {
            get { return _holder; }
        }


        public IDbSource Source
        {
            get { return _source; }
        }
    }
}
